package taper.controller.plc;

import java.awt.Color;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;
import gui.MainGUI;


import db.DatabaseManager;
import db.EntityWrapper;
import db.entity.PadLife;
import db.entity.PadLifePK;
import db.entity.PadeLapse;
import db.entity.PadeLapsePK;
import db.entity.Padlot;
import db.entity.StationConnection;
import db.entity.StationStatus;
import db.entity.TaperValue;


import taper.controller.ComPort;
import taper.controller.MewtocolCommand;
import taper.controller.TaperController;
import taper.controller.wcs.WCSExcelProcessor;
import util.Constants;
import util.PropertiesLoader;
import util.UnitConversion;



public class RegisterReader {
	private static final Logger log = Logger.getLogger(RegisterReader.class);
	
	
	public void startRead() {
		new Thread(new Runnable() {
			public void run() {
				
				while (true) {
					try {
						Iterator iter = TaperController.activeStationMap.values().iterator();

						while (iter.hasNext()) {
							StationStatus station = (StationStatus) iter.next();
							String stationName = station.getId().getName();

//							String runningFlag = "";
//							try {
//								//Read polishing flag
//								String flag = ComPort.getInstance().sendMewtocol(MewtocolCommand.readContact(stationName, "0081"));
//
//								//1 = start polishing , 0 = stop polishing
//								runningFlag = flag.substring(6, 7);
// 
//								//log.info("R81 polishing =" + runningFlag+" Station:"+stationName);
//							} catch (Exception e) {
//								log.error("MonitorProcessor:processMonitorResult",e);
//							}
							Boolean isPolishing = (Boolean) MonitorProcessor.isPolishingMap.get(stationName);
							if (isPolishing) {
								 monitorRegister(stationName);
							}
							
						}
						Thread.sleep(PropertiesLoader.getRegisterReaderInterval());
				
					} catch (Exception e) {
						log.error("MonitorProcessor:startMonitor",e);
					}

				}
			}
		}).start();
	}

	public void monitorRegister(String stationName) {

		try {
			String respond = ComPort.getInstance().sendMewtocol(MewtocolCommand.monitor(stationName));
			process(respond);
		} catch (Exception e) {
			log.error("MonitorProcessor:monitorRegister",e);
			
			MainGUI.updateConnection(Integer.parseInt(stationName),Constants.STATION_DISCONNECTED);
		}

	}

	  public void process(String rawData)
	   {
	     String stationID = getStationName(rawData);
	     String respondType = getRespondType(rawData);
	
	     log.info("rawData :" + rawData);
	
	     if (respondType.equals(MewtocolCommand.error))
	     {
	       log.info("rawData error:" + rawData);
	     } else if (respondType.equals(MewtocolCommand.noError)) {
	       String command = getCommand(rawData);
	       if (command.equals(MewtocolCommand.monitorResult))
	       {
	    	   
	    	   //if (rawData.length() == 40)
	    	   if (rawData.length() == 36)
	    		   rawData = rawData.substring(0, 6) + rawData.substring(8);

	        // if (rawData.length() == 38)
	    	   if (rawData.length() == 34)
	           processMonitorResult(rawData);
	         else
	          try
	           {
	             String respond = ComPort.getInstance().sendMewtocol((MewtocolCommand.resetMonitor(stationID)));
	
	            respond =  ComPort.getInstance().sendMewtocol(MewtocolCommand.registerMonitor(stationID, MewtocolCommand.monitorData));
	            
	             respond = ComPort.getInstance().sendMewtocol(MewtocolCommand.monitor(stationID));
	             
	             if (respond.length() == 36)
	            	 respond = rawData.substring(0, 6) + rawData.substring(8);
	             if (respond.length() == 34)
		           processMonitorResult(respond);
		    	   
	           }
	         catch (Exception e) {
	        	 log.error("MonitorProcessor:process",e);
	           }
	      }
	     }
	   }
	  
	public void processMonitorResult(String rawData) {
		String stationName = getStationName(rawData);

		//Read left vacuum
		float dt04 = UnitConversion.plcHexToReadeable(rawData.substring(11, 15));
		
		//Read Right vacuum
		float dt08 = UnitConversion.plcHexToReadeable(rawData.substring(15, 19));

		//Read Left pressure
		float dt12 = UnitConversion.plcHexToReadeable(rawData.substring(19, 23));
		
		//Read Right pressure
		float dt16 = UnitConversion.plcHexToReadeable(rawData.substring(23, 27));
		
		//Read temperature 
		float dt18 = UnitConversion.plcHexToReadeable(rawData.substring(27, 31));
		
//		float dt04 = UnitConversion.plcHexToReadeable(rawData.substring(15, 19));
//		
//		//Read Right vacuum
//		float dt08 = UnitConversion.plcHexToReadeable(rawData.substring(19, 23));
//
//		//Read Left pressure
//		float dt12 = UnitConversion.plcHexToReadeable(rawData.substring(23, 27));
//		
//		//Read Right pressure
//		float dt16 = UnitConversion.plcHexToReadeable(rawData.substring(27, 31));
//		
//		//Read temperature 
//		float dt18 = UnitConversion.plcHexToReadeable(rawData.substring(31, 35));
		
		log.info("Station Name: "+stationName+" Left vacuum dt04:"+dt04+" Right vacuum dt08:"+dt08+" Left pressure dt12:"+dt12+" Right pressure dt16:"+dt16+" temperature dt18:"+dt18);

			StationStatus station = (StationStatus) TaperController.activeStationMap.get(stationName);
			
				station.setTemperature(UnitConversion.plcToTemperatureDegree(dt18));
				station.setVacuumLeft(UnitConversion.plcToInchesHg(dt04));
				station.setPressureLeft(UnitConversion.plcToPsi(dt12));
				station.setVacuumRight(UnitConversion.plcToInchesHg(dt08));
				station.setPressureRight(UnitConversion.plcToPsi(dt16));
				station.getId().setDataDate(new Date());
	
				EntityWrapper<StationStatus> db = new EntityWrapper<StationStatus>( );
			    db.merge(station); 
			    db.commit();

	}
	  
	  public String getRespondType(String rawData) {
		     return rawData.substring(3, 4);
	  }
		 
	  public String getStationName(String rawData) {
		 return rawData.substring(1, 3);
	 }
	  
	  public String getCommand(String rawData)
	  {
	  return rawData.substring(4, 6);
	  }
}
